package vip.zhenzicheng.concurrent_program.thread;

import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * <p>原生线程池 7个核心参数 4个拒绝策略</p>
 * parameters.
 * <dl>
 * <dt>corePoolSize</dt>
 * <dd>
 *   核心线程数[一直存在除非指定了 {@code allowCoreThreadTimeOut} - 允许核心线程超时]，注意：如果仅指定了存活时间，核心线程不受影响。
 *   线程池创建好以后准备就绪的线程数量，等待接收异步方法任务去执行。corePoolSize=5 相当于 new Thread() * 5 然后放入线程池中。
 *   注意：没有调用start()方法;
 * </dd>
 * <dt>maximumPoolSize</dt>
 * <dd>
 *   最大线程数量，用来控制资源；
 *   如果达到最大线程数量，则剩余请求会等待池中有空闲线程后在执行
 * </dd>
 * <dt>keepAliveTime</dt>
 * <dd>
 *   存活时间。如果线程数量大于{@code corePoolSize}核心线程数量，则多出的线程在超过存活时间后会被释放。
 * </dd>
 * <dt>unit</dt>
 * <dd>时间单位</dd>
 * <dt>workQueue</dt>
 * <dd>
 *   阻塞队列。如果任务较多，则超过最大能处理部分的任务则会放在队列中。只要有线程空闲，就会去队列中取出新的任务继续执行。
 * </dd>
 * <dt>threadFactory</dt>
 * <dd>线程的创建工厂。可以自定义线程创建的方式</dd>
 * <dt>handler</dt>
 * <dd>
 *   如果线程池和队列都应满了，则按照自定义的拒绝策略，拒绝执行任务
 * </dd>
 * </dl>
 *
 * @author zhenzicheng
 * @DESCRIPTION: 线程池demo
 * @DATE: 2022/05/09 6:04 PM
 */
public class ThreadPoolDemo {

  public static void main(String[] args) {
    executorDemo();


  }

  public static void executorDemo() {

    ThreadPoolExecutor executor = new ThreadPoolExecutor(
        5,
        200,
        10,
        TimeUnit.SECONDS,
        new LinkedBlockingQueue<>(),
        Executors.defaultThreadFactory(),
        new ThreadPoolExecutor.AbortPolicy()
    );
    executor.allowCoreThreadTimeOut(true);
  }

  /**
   * 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程
   */
  public static void cachedThreadPool() {
    Executors.newCachedThreadPool();
  }

  /**
   * 创建一个定长线程池，可控制线程最大并发数，超出的线程会在队列中等待。
   */
  public static void fixedThreadPool() {
    Executors.newFixedThreadPool(50);
  }

  /**
   * 创建一个定长线程池，支持定时以及周期性任务执行
   */
  public static void scheduledThreadPool() {
    Executors.newScheduledThreadPool(20);
  }

  /**
   * 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务
   */
  public static void singleThreadExecutor() {
    Executors.newSingleThreadExecutor();
  }

}
